﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_CL_EVENT_H
#define _UXS_CL_EVENT_H

#pragma once

#include "CLDevice.h"

namespace UX_STL
{
namespace CLShell
{

	//
	// CL Event Callback
	//

	class ICLEventCallback
	{
	public:
		virtual void operator () (CLEvent *pEvent, cl_event_status::type eStatus) = 0;
	};


	//
	// CL Event
	//

	class UX_EXPORT CLEvent : public CLBaseObject
	{
	protected:
		cl_event			_pID;
		ICLEventCallback *	_pCallback;
		
	protected:
		virtual void _RetainRef()	const;
		virtual void _ReleaseRef()	const;
		virtual uint _GetRefCount()	const;
		virtual void _Destroy();

		static void CALLBACK _s_Callback(cl_event pEvent, cl_int iStatus, void *pUserData);

	public:
		CLEvent();
		CLEvent(cl_event pEvent);
		~CLEvent();

		bool  Create(ICLEventCallback *pCallback = null);
		void  Destroy();
		
		bool  Wait() const;
		void  SetCallback(ICLEventCallback *pCallback);
		bool  GetCommandType(cl_event_command::type &eType) const;
		bool  GetStatus(cl_event_status::type &eType) const;
		bool  SetStatus(cl_event_status::type eType = cl_event_status::COMPLETE);
		bool  GetProfilingTime(cl_event_time::type eType, uint64 &uTime) const;

		cl_event	Id()	 const	{ return _pID; }

		static bool s_Wait(const clevent_uni_array &aEvents);
	};



	//
	// CL Events array
	//

	struct CLEventArray
	{
	public:
		typedef uni_array< CLEvent *>								event_uni_array_t;
		typedef array< cl_event, TFastCopyStrategy< cl_event > >	clevent_array_t;

	private:
		clevent_array_t		_aEventArray;

	public:
		CLEventArray(const event_uni_array_t &);

		operator const clevent_uni_array () const	{ return (clevent_uni_array)_aEventArray; }
	};




//-------------------------- CLEventArray -------------------------//

	inline CLEventArray::CLEventArray(const event_uni_array_t &aEvents)
	{
		_aEventArray.Reserve( aEvents.Count() );

		FOR( i, aEvents ) {
			_aEventArray.PushBack( aEvents[i]->Id() );
		}
	}

//-------------------------------------------------------------------

}	// CLShell
}	// UX_STL

#endif	// _UXS_CL_EVENT_H